# networkX_E3.py
# Demo of shortest path with NetworkX
# Copyright 2021 YouCans, XUPT
# Crated：2021-05-20

import copy
import csv
import json

import matplotlib.colors as mcolors
import matplotlib.pyplot as plt  # 导入 Matplotlib 工具包
import networkx as nx  # 导入 NetworkX 工具包
import numpy as np
import pandas as pd

from .import base_fun as fun
# import base_fun as fun

def view_maps(view):

    points = []
    out_edges = []
    with open("D:/session/map/RoadLine.json", 'rb') as load_f:
        RoadLine = json.load(load_f)
    point_cnt = 0
    for line_id, rd in enumerate(RoadLine):  # len(RoadLine)):
        dt = rd["geometry"]["coordinates"]
        if dt == []:
            continue

        index_zero = point_cnt
        # npdt=np.array(dt)
        points += dt

        # print(index_zero)
        for id in range(len(dt)-1):
            node_id1 = id+index_zero
            val_dis = fun.GetDistance(points[node_id1], points[node_id1+1])
            if(val_dis != -1):
                out_edges.append((node_id1, node_id1+1, val_dis))
                continue
            out_edges.append((node_id1, node_id1+1, 0))
            # print(node_id1,node_id1+1,points[node_id1],points[node_id1+1]) #,dt[node_id1],npdt[node_id1+1],val_dis)
            # del points[node_id1+1]

        point_cnt += len(dt)
        # break
    # print(point_cnt)
    # print(points)
    # print(cnt)
    with open("D:/session/map/RoadPoint.json", 'rb') as load_f:
        RoadPoint = json.load(load_f)
    np_points = np.array(points)

    # print(RoadPoint)
    # print(vasum)
    # print(np_points[0],np_points[1],fun.GetDistance(np_points[0],np_points[1]))

    for rd in RoadPoint:  # len(RoadLine)):
        dt = rd["geometry"]["coordinates"]
        for p2_index, p2 in enumerate(points):
            val_dis = fun.GetDistance222(dt, p2)
            valll = dt-np_points
            if(val_dis < (1e-4)):
                print(val_dis, p2_index, rd["properties"]
                      ["osm_id"], rd["properties"]["osm_id_2"])

            # break

    #     if dt == []:
    #         continue
    #     for id,val in dt:

    #     if view:
    #         dtarray = np.array(dt)
    #         plt.scatter(dtarray[1], dtarray[0],
    #                     color=colors[0], edgecolors='none', s=10, linewidth=0.50)
    return points



def calrandmpath(gant, source, target):
    paths = nx.single_source_shortest_path(gant, source)
    print("len:", len(paths))
    return paths
# gAnt=mnx(out_edges, dictpoints)
# calrandmpath(gAnt,0,15000)


def calrandmpath_1(gant, source, target):
    paths = nx.single_source_shortest_path(gant, source)
    print("len:", len(paths))
    return paths


def fix_people_id(points, rescue_peoples, roadpoint):
    poeple_info = []
    nppoints = np.array(points)
    # print(rescue_peoples[0])
    for id, (point, people_id, type) in enumerate(rescue_peoples):
        ret = np.fabs(nppoints-point)
        su = np.sum(ret, axis=1)
        m1_id = np.where(su == np.min(su))
        for p1, p2 in roadpoint:
            if p2 == m1_id[0][0]:
                m1_id[0][0] = p1
        # print(ret)
        # print(ret[m1_id[0][0]],nppoints[m1_id[0][0]],point)
        poeple_info.append((point, people_id, type, m1_id[0][0]))
    # print(poeple_info[0])

    return poeple_info


def cal_path_weight_people(path, poeple_info):
    p_num = 0
    t_num = 0
    for id, (point, people_id, type, point_id) in enumerate(poeple_info):
        if point_id in path:
            p_num += 1
            t_num += type
    # if t_num>42:
    print("人数:", p_num, "分数:", t_num)
    return t_num


def path_2_csv(path, p2, p3, strname):
    f = open(strname, 'w', encoding='utf-8', newline='')
    csv_writer = csv.writer(f)
    csv_writer.writerow(path)
    csv_writer.writerow(p2)
    csv_writer.writerow(p3)
    f.close()


def path_2_pdm(points, path, p2, p3, strname):
    _lpoints = [[], [], [], [], [], []]
    for val in path:
        _lpoints[0].append(points[val])
    for val in p2:
        _lpoints[1].append(points[val])
    for val in p3:
        _lpoints[2].append(points[val])
    _lpoints[3] = copy.deepcopy(_lpoints[0])
    _lpoints[4] = copy.deepcopy(_lpoints[1])
    _lpoints[5] = copy.deepcopy(_lpoints[2])
    _lpoints[0].extend(_lpoints[3])
    _lpoints[1].extend(_lpoints[4])
    _lpoints[2].extend(_lpoints[5])
    alldata = _lpoints[0]+_lpoints[1]+_lpoints[2]
    data1 = pd.DataFrame(alldata, columns=['longitude', 'latitude'])
    return data1


def deledge(gant, path):
    for i in range(len(path)-1):
        gant.remove_edge(path[i], path[i+1])  # 删除边 (13,17)


def trf_id(points, pltlins, poeple_info):
    ret = []
    new_path_node = copy.deepcopy(pltlins)

    for _id, val in enumerate(pltlins[0]):
        new_path_node[0][_id] = poeple_info[val-1][3]
        # print(val,"       ",poeple_info[val-1],new_path_node[0][_id])
    for _id, val in enumerate(pltlins[1]):
        new_path_node[1][_id] = poeple_info[val-1][3]
    for _id, val in enumerate(pltlins[2]):
        new_path_node[2][_id] = poeple_info[val-1][3]
    #             break
    # for _id,val in enumerate(pltlins[1]):
    #     for id, (point, people_id, type, point_id) in enumerate(poeple_info):
    #         if people_id == val:
    #             new_path_node[1][id]=point_id
    #             break
    # for _id,val in enumerate(pltlins[2]):
    #     for id, (point, people_id, type, point_id) in enumerate(poeple_info):
    #         if people_id == val:
    #             new_path_node[2][id]=point_id
    #             break
    return new_path_node


def gen_points_paths(gant, passpoints):
    # print("经过点:", passpoints)
    for i in range(len(passpoints) - 1, -1, -1):
        if not passpoints[i] in gant:
            del passpoints[i]
    while(True):
        flist = 0
        for i in range(len(passpoints) - 1, -1, -1):
            val = nx.algorithms.shortest_paths.generic.has_path(
                gant, passpoints[i-1], passpoints[i])
            if(val == False):
                del passpoints[i]
                flist += 1
        if flist > 0:
            mbool = False
        else:
            break
        # print(flist)
    path = []
    for i in range(len(passpoints)-1):
        try:
            _pp = nx.astar_path(gant, passpoints[i], passpoints[i+1])
            path += _pp
        except:
            print(passpoints[i], passpoints[i+1])
    # path+=nx.astar_path(gant, passpoints[i], passpoints[0])
    return path
# def id_filter(new_path_node):


def red_step_1path():
    path = './data/gen_people_75id.csv'
    read_csv = csv.reader(open(path, 'r'), dialect='excel')

    _ldd = 0
    pltlins = []
    for line in read_csv:  # 循环输出csv中的所有数据
        pltlins.append(list(int(val) for val in line))
    # print(pltlins)#行人ID
    return pltlins
def red_step_1path_pandas(sd0):
    pltlins = []
    for i in range(3):
        val= sd0[i]['people_id'].values.astype("int")
        pltlins.append(list(val))
    # print(pltlins)
   
    return pltlins

def _main_fun(sdo0,round_id):
    points, roadLines, roadpoint = view_maps2(False)  # 读取地图
    out_edges, dictpoints = perdata(roadLines,points)  # 修正数据
    rescue_peoples = fun.read_client_path_new(round_id)  # 读取行人数据
    poeple_info = fix_people_id(points, rescue_peoples, roadpoint)
    gant = mnx(out_edges, dictpoints)
    # print(roadpoint)
    # for id, (point, people_id, type, point_id) in enumerate(poeple_info):
    #     if not point_id in gant:
    #         print(point_id)
    pltlins = red_step_1path_pandas(sdo0)  # 行人ID
    new_path_node = trf_id(points, pltlins, poeple_info)
    #
    path1 = [[], [], []]
    data = []
    for i in range(3):
        
        path1[0] = gen_points_paths(gant, new_path_node[i][0:30])
        path1[1] = gen_points_paths(gant, new_path_node[i][30:60])
        path1[2] = gen_points_paths(gant, new_path_node[i][60:])
        ret = cal_path_weight_people(path1[0], poeple_info)
        ret = cal_path_weight_people(path1[1], poeple_info)
        ret = cal_path_weight_people(path1[2], poeple_info)
        # path_2_csv(path1[0], path1[2], path1[1], './data/gen_people_1.csv')
        data.append(path_2_pdm(
            points, path1[0], path1[1], path1[2], './data/gen_people_1.json'))
    stringname = 'D:/session/session_2/subject_2/team_path_'+str(round_id)+'.json'
    fun.toJons((data[0], data[1], data[2]), stringname,round_id)

# if __name__ == '__main__':
    # _main_fun(sdo0)
